package de.koller.worlders.engine.entity;

import de.koller.oceanFramework.math.ROVec;
import de.koller.oceanFramework.math.Vec;
import de.koller.oceanFramework.tree.Child;
import de.koller.oceanFramework.tree.ISea3;
import de.koller.oceanFramework.tree.Sea3X;
import de.koller.oceanFramework.util.MIn;
import de.koller.oceanFramework.util.OceanSet;
import de.koller.worlders.WSea;
import de.koller.worlders.engine.entity.enc.EncRoot;
import de.koller.worlders.engine.entity.mo.MovingObject;
import de.koller.worlders.engine.entity.mo.Player;
import de.koller.worlders.engine.entity.mo.grav.Gravitron;
import de.koller.worlders.engine.entity.mo.phsics.Physics;
import de.koller.worlders.engine.entity.mo.topdown.TopDownPlayer;
import de.koller.worlders.engine.entity.mo.vehicle.Ufo;
import de.koller.worlders.engine.entity.zone.ResetZone;
import de.koller.worlders.engine.tiles.MOTile;
import de.koller.worlders.engine.tiles.data.MapData;
import de.koller.worlders.gameplay.IGameplayPlayerObject;
import de.koller.worlders.render.VisualMap;
import java.util.HashSet;
import java.util.Set;
import org.lwjgl.input.Keyboard;

public class EntityContainer extends WSea {

	public final OceanSet<Gravitron> gravitrons = new OceanSet<>();
	private final Vec defaultForce = new Vec( 0, MovingObject.GRAVITY );

	private Vec reseter = new Vec();
	private Set<ResetZone> reseters = new HashSet<>();
	
	private final Set<MOTile> moTiles = new HashSet<>();
//	private final Set<Elevator> elevators = new HashSet<>();
	@Child private final Physics physics = new Physics();
//	@Child public final WPhysicsRoot wphysics = new WPhysicsRoot();
	
	@Child private final WSea resetNode = new WSea();
	@Child private final PortalEntities portalEntities = new PortalEntities();
	@Child public final EncRoot enc = new EncRoot();
	
	private boolean showCrosshair = false;
	private final Vec mouseWorldPosition = new Vec();
	//@Child private final GUMob gutest = new GUMob( 63, 60, 0xff00ff00 );
	
	private int playerSwitch = 0;
	private IGameplayPlayerObject myPlayer = null;
	
	@Override
	protected void init() {
		super.init();
		
		myPlayer = new Player( 0, 0 );
		this.addChild( (ISea3)myPlayer );
		wroot.gamePlayer.setGPO( myPlayer );
		
		resetSpawn();
		
		load();
	}

	public ROVec getWorldForce( MovingObject mo ) {
		Vec f = defaultForce;
//		if( !gravitrons.isEmpty() ) {
//			f = new Vec();
//			for( Gravitron g : gravitrons )
//				f.add( g.getForce( mo ) );
//		}
		
		if( !mo.mostate.isGravityAffected() )
			return new Vec();
		if( mo.mostate.isGravityInversed() )
			return f.getInverse();
		return f;
	}
	
	@Override
	protected void update( int elapsedTime ) {
		super.update( elapsedTime );
		
		gravitrons.update();
		
		//@todo delete playerswitching
		if( wroot.getInput().isKeyPressed( Keyboard.KEY_BACK ) ) {
			playerSwitch++;
			playerSwitch %= 3;
			
			this.removeChild( (ISea3)myPlayer );
			wroot.gamePlayer.setGPO( null );
			
			if( playerSwitch == 2 )
				myPlayer = new Ufo( 0, 0 );
			if( playerSwitch == 0 )
				myPlayer = new Player( 0, 0 );
			if( playerSwitch == 1 )
				myPlayer = new TopDownPlayer( 0, 0 );
			
			this.addChild( (ISea3)myPlayer );
			wroot.gamePlayer.setGPO( myPlayer );
		}
			
		
		int mx = wroot.getInput().getMouseX();
		int my = wroot.getInput().getMouseY();
		
		wroot.rendering.worlderV.setTransform();
		mouseWorldPosition.set( wroot.rendering.worlderV.getWorldPosition( mx, my ) );
		wroot.rendering.worlderV.unsetTransform();
	}
	
	public void resetSpawn() {
		getReseter().set( MapData.MAP_SIZE / 2, MapData.MAP_SIZE / 2 - 4 );
	}
	
	private void load() {	
		MIn i = new MIn( wroot.getUser().getUserpath() + "player.2mp" );
		float x = i.readFloat( 1 )[0];
		float y = i.readFloat( 1 )[0];
		i.close();
		
		if( x == 0 && y == 0 )
			return;
		else
			reseter.set( x, y );
	}

	public Vec getReseter() {
		return reseter;
	}

	public Set<MOTile> getMoTiles() {
		return moTiles;
	}

	public Physics getPhysics() {
		return physics;
	}

//	public Set<Elevator> getElevators() {
//		return elevators;
//	}

	public Set<ResetZone> getReseters() {
		return reseters;
	}
	
	public void reseterEntered( ResetZone rz ) {
		reseter.set( rz.getZone().getPosition().getXi(), rz.getZone().getPosition().getYi() );
		for( ResetZone r : reseters )
			r.getZone().getTile().setVisual( VisualMap.resetOff );
		rz.getZone().getTile().setVisual( VisualMap.resetOn );
	}

	public WSea getResetNode() {
		return resetNode;
	}

	@Override
	protected void resetNodeNotify() {
		super.resetNodeNotify();
		
		for( ISea3 s : resetNode.getSeas() )
			((Sea3X)s).removeMe();	
		
	}

	public PortalEntities getPortalEntities() {
		return portalEntities;
	}

	public Vec getMouseWorldPosition() {
		return mouseWorldPosition;
	}

	public boolean isShowCrosshair() {
		return showCrosshair;
	}

	public void setShowCrosshair( boolean showCrosshair ) {
		this.showCrosshair = showCrosshair;
	}

}
